Skip to content

feat(notifications): email on schedule auto-disable and 100% usage limit - #6038

Open
TheodoreSpeaks wants to merge 2 commits into
stagingfrom
feat/email-notify
Open

feat(notifications): email on schedule auto-disable and 100% usage limit#6038
TheodoreSpeaks wants to merge 2 commits into
stagingfrom
feat/email-notify

Conversation

@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator

Summary

  • Email the workflow creator and workspace admins when Sim auto-disables a schedule — covers all nine disable paths, including the single-strike 401/403/404 ones that bypass the failure counter entirely
  • Fix the 100%-credits email skipping paid and org accounts: it was gated on isFreeUser plus scope === 'user', so a Pro user or an entire Team org got blocked at admission with no notice
  • Paid/org accounts get a new "raise your limit" email — upgrading to Pro isn't their remedy; free personal accounts keep the existing upgrade-framed one
  • Add !crosses100 to the paid 80% branch so one execution crossing both thresholds sends "reached" alone, not "nearing" and "reached" together

Notes

  • applyScheduleUpdate now returns { updated, status } and takes a disableReason. Passing a reason also adds a status <> 'disabled' guard — Postgres RETURNING yields the new row, so status === 'disabled' alone means "is disabled", not "just became disabled".
  • The stale-recovery sweep keeps its write inside the transaction and flushes notifications after commit, capped at 25 per tick.
  • One email per recipient, never a to: array — prepare.ts only checks to[0] for unsubscribe.
  • The 100% path still uses crossing detection, so it inherits the existing weaknesses (a failed send is lost; concurrent completions can double-send). Moving all four credit emails onto limit-notifications.ts's race-free claim is a follow-up.

Type of Change

  • New feature (schedule notification) + bug fix (credits gating)

Testing

  • 405 tests passing across the touched suites; new coverage for recipient resolution, the disable edge, the org fan-out, and both templates rendered for real
  • bun run lint, bun run type-check, check:api-validation:strict and the full audit suite pass
  • No migrations in this change

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel

vercel Bot commented Jul 29, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jul 29, 2026 1:40am

Request Review

@cursor

cursor Bot commented Jul 29, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches schedule execution failure handling and billing notification delivery; mistakes could duplicate or miss emails, but mail is best-effort and does not block ticks or mutations.

Overview
Schedule auto-disable notifications email the schedule creator and workspace admins when Sim turns off a workflow or job schedule. A new notifyScheduleAutoDisabled helper fans out ScheduleDisabledEmail with reason-specific copy; schedule writes go through applyScheduleUpdate / applyScheduleFailureUpdate with a status <> 'disabled' guard so notifications fire only on an active → disabled transition. The cron execute route and stale job recovery defer mail until after commit and cap batch notifications.

100% usage limit fixes paid and organization accounts that previously got no email at full usage (only free personal users did). They now receive UsageLimitReachedEmail with billing-settings CTAs; free personal accounts still get the upgrade-oriented exhausted-credits template. Org delivery goes to admins only; crossing 80% and 100% in one step sends a single “reached” message.

New email previews, render tests, and broad unit coverage accompany the billing and schedule paths.

Reviewed by Cursor Bugbot for commit 10eb774. Bugbot is set up for automated code reviews on this repo. Configure here.

@greptile-apps

greptile-apps Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds schedule auto-disable emails and fixes 100% usage-limit notices for paid/org accounts.

  • Wires applyScheduleUpdate / applyScheduleFailureUpdate so disable-capable paths detect an active → disabled edge and notify creator + workspace admins (including deferred post-commit notify for stale recovery, capped at 25).
  • New ScheduleDisabledEmail and UsageLimitReachedEmail templates, subjects, preview routes, and render helpers.
  • maybeSendUsageThresholdEmail now sends at 100% for all plans/scopes (raise-limit copy for paid/org; existing free exhausted copy for free personal), with !crosses100 on the 80% branches to avoid double-send.

Confidence Score: 5/5

This PR appears safe to merge; no blocking failures remain from prior or current follow-up review.

No blocking failure remains.

Important Files Changed

Filename Overview
apps/sim/background/schedule-execution.ts Guarded schedule updates return status, opt into one-shot disable notify via disableReason, and export failure-update helper with deferred notification.
apps/sim/app/api/schedules/execute/route.ts Setup-failure and stale-recovery paths use applyScheduleFailureUpdate and notify only when a row newly disables; recovery notify is post-commit and capped.
apps/sim/lib/workflows/schedules/disable-notifications.ts Best-effort fan-out to schedule creator and workspace admins with per-recipient sends and recipient cap.
apps/sim/lib/billing/core/usage.ts 100% threshold emails for paid/org with raise-limit template; free personal keeps exhausted copy; 80% suppressed when 100% crossed in same call.
apps/sim/components/emails/notifications/schedule-disabled-email.tsx New schedule-disabled notification template with reason copy and manage CTA.
apps/sim/components/emails/billing/usage-limit-reached-email.tsx New paid/org 100% usage limit email with raise-limit CTA by scope.

Sequence Diagram

sequenceDiagram
  participant Tick as Schedule tick / job
  participant Upd as applyScheduleUpdate
  participant DB as workflow_schedule
  participant Nfy as notifyScheduleAutoDisabled
  participant Mail as sendEmail

  Tick->>Upd: update with disableReason
  Upd->>DB: "UPDATE ... status <> disabled RETURNING status"
  alt status became disabled and not deferred
    Upd->>Nfy: notifyScheduleAutoDisabled
    Nfy->>Mail: creator + workspace admins
  else deferred (stale recovery)
    Tick->>DB: commit transaction
    Tick->>Nfy: flush disabled ids (cap 25)
    Nfy->>Mail: creator + workspace admins
  end
Loading

Reviews (2): Last reviewed commit: "fix(notifications): keep partial recipie..." | Re-trigger Greptile

Comment thread apps/sim/lib/workflows/schedules/disable-notifications.ts
@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator Author

@greptile

@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 10eb774. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant